namespace iScadaFBD
{
    using System;
    using System.Collections;
    using System.Drawing;
    using System.Windows.Forms;

    [Serializable]
    public class Connection : DrawObject
    {
        private FBObject attachFromFB;
        private int attachFromNode;
        private FBObject attachToFB;
        private int attachToNode;
        private Point endPoint;
        private bool flagA;
        private bool flagB;
        private ArrayList lineList = new ArrayList();
        private int mid0;
        private int mid1;
        private int mid2;
        private Point startPoint;

        public Connection(FBObject attach_FromFB, int attach_FromNode, FBObject attach_ToFB, int attach_ToNode, DrawArea drawArea)
        {
            base.ObjectType = GlobalParam.ObjectType.Connection;
            this.attachFromFB = attach_FromFB;
            this.attachFromNode = attach_FromNode;
            this.attachToFB = attach_ToFB;
            this.attachToNode = attach_ToNode;
            this.startPoint = this.GetStartPoint(this.attachFromFB, this.attachFromNode);
            this.endPoint = this.GetEndPoint(this.attachToFB, this.attachToNode);
            if (this.attachFromFB != this.attachToFB)
            {
                if (this.startPoint.X < this.endPoint.X)
                {
                    this.mid0 = (this.attachFromFB.FBRect.Right + this.attachFromFB.FBRect.Left) / 2;
                    this.flagA = true;
                    this.flagB = false;
                }
                if (this.startPoint.X > this.endPoint.X)
                {
                    this.mid0 = this.attachFromFB.FBRect.Right + 15;
                    this.mid1 = (this.attachFromFB.FBRect.Bottom + this.attachToFB.FBRect.Top) / 2;
                    this.mid2 = this.attachToFB.FBRect.Left - 15;
                    this.flagA = false;
                    this.flagB = true;
                }
            }
            else
            {
                this.mid0 = this.attachFromFB.FBRect.Right + 15;
                this.mid1 = this.attachFromFB.FBRect.Top - 15;
                this.mid2 = this.attachFromFB.FBRect.Left - 15;
            }
            this.AddLine();
        }

        private void ActiveLine(Graphics g)
        {
            this.startPoint = this.GetStartPoint(this.attachFromFB, this.attachFromNode);
            this.endPoint = this.GetEndPoint(this.attachToFB, this.attachToNode);
            Line line = (Line) this.lineList[0];
            line.StartPoint = this.startPoint;
            Line line2 = (Line) this.lineList[1];
            Line line3 = (Line) this.lineList[2];
            Line line4 = (Line) this.lineList[3];
            Line line5 = (Line) this.lineList[4];
            line5.EndPoint = this.endPoint;
            if (this.startPoint.X < this.endPoint.X)
            {
                if (this.flagA)
                {
                    this.mid0 = (this.startPoint.X + this.endPoint.X) / 2;
                    this.flagA = false;
                }
                this.flagB = true;
                line.MovedAble = false;
                line.EndPoint = new Point(this.mid0, this.startPoint.Y);
                line2.MovedAble = false;
                line2.StartPoint = new Point(this.mid0, this.startPoint.Y);
                line2.EndPoint = new Point(this.mid0, this.startPoint.Y);
                line3.MovedAble = true;
                line3.StartPoint = new Point(this.mid0, this.startPoint.Y);
                line3.EndPoint = new Point(this.mid0, this.endPoint.Y);
                line4.MovedAble = false;
                line4.StartPoint = new Point(this.mid0, this.endPoint.Y);
                line4.EndPoint = new Point(this.mid0, this.endPoint.Y);
                line5.MovedAble = false;
                line5.StartPoint = new Point(this.mid0, this.endPoint.Y);
            }
            else
            {
                if (this.flagB)
                {
                    this.mid0 = this.startPoint.X + 15;
                    this.mid1 = (this.startPoint.Y + this.endPoint.Y) / 2;
                    this.mid2 = this.endPoint.X - 15;
                    this.flagB = false;
                }
                this.flagA = true;
                line.MovedAble = false;
                line.EndPoint = new Point(this.mid0, this.startPoint.Y);
                line2.MovedAble = true;
                line2.StartPoint = new Point(this.mid0, this.startPoint.Y);
                line2.EndPoint = new Point(this.mid0, this.mid1);
                line3.MovedAble = true;
                line3.StartPoint = new Point(this.mid0, this.mid1);
                line3.EndPoint = new Point(this.mid2, this.mid1);
                line4.MovedAble = true;
                line4.StartPoint = new Point(this.mid2, this.mid1);
                line4.EndPoint = new Point(this.mid2, this.endPoint.Y);
                line5.MovedAble = false;
                line5.StartPoint = new Point(this.mid2, this.endPoint.Y);
            }
            for (int i = 0; i < this.lineList.Count; i++)
            {
                ((Line) this.lineList[i]).Draw(g);
            }
        }

        public void AddLine()
        {
            Line line;
            Line line2;
            Line line3;
            Line line4;
            Line line5;
            Point point = new Point(0, 0);
            Point point2 = new Point(0, 0);
            if (this.startPoint.X < this.endPoint.X)
            {
                point = new Point(this.startPoint.X, this.startPoint.Y);
                point2 = new Point(this.mid0, this.startPoint.Y);
                line = new Line(point, point2);
                line.MovedAble = false;
                this.lineList.Add(line);
                point = new Point(this.mid0, this.startPoint.Y);
                point2 = new Point(this.mid0, this.startPoint.Y);
                line2 = new Line(point, point2);
                line2.MovedAble = false;
                this.lineList.Add(line2);
                point = new Point(this.mid0, this.startPoint.Y);
                point2 = new Point(this.mid0, this.endPoint.Y);
                line3 = new Line(point, point2);
                line3.MovedAble = true;
                this.lineList.Add(line3);
                point = new Point(this.mid0, this.endPoint.Y);
                point2 = new Point(this.mid0, this.endPoint.Y);
                line4 = new Line(point, point2);
                line4.MovedAble = false;
                this.lineList.Add(line4);
                point = new Point(this.mid0, this.endPoint.Y);
                point2 = new Point(this.endPoint.X, this.endPoint.Y);
                line5 = new Line(point, point2);
                line5.MovedAble = false;
                this.lineList.Add(line5);
            }
            else
            {
                point = new Point(this.startPoint.X, this.startPoint.Y);
                point2 = new Point(this.mid0, this.startPoint.Y);
                line = new Line(point, point2);
                line.MovedAble = false;
                this.lineList.Add(line);
                point = new Point(this.mid0, this.startPoint.Y);
                point2 = new Point(point.X, this.mid1);
                line2 = new Line(point, point2);
                line2.MovedAble = true;
                this.lineList.Add(line2);
                point = new Point(this.mid0, this.mid1);
                point2 = new Point(this.mid2, this.mid1);
                line3 = new Line(point, point2);
                line3.MovedAble = true;
                this.lineList.Add(line3);
                point = new Point(this.mid2, this.mid1);
                point2 = new Point(this.mid2, this.endPoint.Y);
                line4 = new Line(point, point2);
                line4.MovedAble = true;
                this.lineList.Add(line4);
                point = new Point(this.mid2, this.endPoint.Y);
                point2 = new Point(this.endPoint.X, this.endPoint.Y);
                line5 = new Line(point, point2);
                line5.MovedAble = false;
                this.lineList.Add(line5);
            }
        }

        public override void Draw(Graphics g, DrawArea drawArea)
        {
            this.ActiveLine(g);
        }

        public Point GetEndPoint(FBObject toFB, int toNode)
        {
            if (toFB != null)
            {
                for (int i = 0; i < toFB.InNodeList.Count; i++)
                {
                    if (toNode >= 0)
                    {
                        return toFB.LinkInPoint(toNode);
                    }
                }
            }
            return this.endPoint;
        }

        public override Point GetHandle(int handleNumber)
        {
            if (handleNumber == 1)
            {
                return this.startPoint;
            }
            return this.endPoint;
        }

        public Cursor GetMoveCursor(Point point)
        {
            if (this.GetSelectedLine(point) != null)
            {
                return this.GetSelectedLine(point).GetCursor(point);
            }
            return Cursors.Default;
        }

        public int GetMoveLineIndex(Point point)
        {
            for (int i = 0; i < this.lineList.Count; i++)
            {
                Line line = (Line) this.lineList[i];
                if (line.PointNearLine(point))
                {
                    return i;
                }
            }
            return -1;
        }

        public Line GetSelectedLine(Point point)
        {
            for (int i = 0; i < this.lineList.Count; i++)
            {
                Line line = (Line) this.lineList[i];
                if (line.PointNearLine(point))
                {
                    return line;
                }
            }
            return null;
        }

        public Point GetStartPoint(FBObject fromFB, int fromNode)
        {
            if (fromFB != null)
            {
                for (int i = 0; i < fromFB.OutNodeList.Count; i++)
                {
                    if (fromNode >= 0)
                    {
                        return fromFB.LinkOutPoint(fromNode);
                    }
                }
            }
            return this.startPoint;
        }

        public override int HitTest(Point point)
        {
            if (base.Selected)
            {
                for (int i = 1; i <= this.HandleCount; i++)
                {
                    if (this.GetHandleRectangle(i).Contains(point))
                    {
                        return i;
                    }
                }
            }
            if (this.PointInObject(point))
            {
                return 0;
            }
            return -1;
        }

        public override bool IntersectsWith(Rectangle rectangle)
        {
            return (rectangle.Contains(this.startPoint) && rectangle.Contains(this.endPoint));
        }

        public override void Move(int deltaX, int deltaY)
        {
            this.mid0 += deltaX;
            this.mid1 += deltaY;
            this.mid2 += deltaX;
        }

        public override void MoveHandleTo(Point point, int handleNumber)
        {
            if (handleNumber == 1)
            {
                this.startPoint = point;
            }
            else
            {
                this.endPoint = point;
            }
        }

        public void MoveLine(Point point, int lineIndex)
        {
            this.startPoint = this.GetStartPoint(this.attachFromFB, this.attachFromNode);
            this.endPoint = this.GetEndPoint(this.attachToFB, this.attachToNode);
            if (this.startPoint.X >= this.endPoint.X)
            {
                switch (lineIndex)
                {
                    case 0:
                    case 1:
                        this.Mid0 = point.X;
                        return;

                    case 2:
                        this.Mid1 = point.Y;
                        return;

                    case 3:
                        this.Mid2 = point.X;
                        return;

                    case 4:
                        return;
                }
            }
            else
            {
                switch (lineIndex)
                {
                    case 0:
                    case 1:
                    case 2:
                        this.Mid0 = point.X;
                        return;

                    case 3:
                    case 4:
                        return;
                }
            }
        }

        public override bool PointInObject(Point point)
        {
            bool flag = false;
            if (this.lineList == null)
            {
                return false;
            }
            for (int i = 0; i < this.lineList.Count; i++)
            {
                Line line = (Line) this.lineList[i];
                flag = flag || line.PointNearLine(point);
            }
            return flag;
        }

        public FBObject AttachFromFB
        {
            get
            {
                return this.attachFromFB;
            }
            set
            {
                this.attachFromFB = value;
            }
        }

        public int AttachFromNode
        {
            get
            {
                return this.attachFromNode;
            }
            set
            {
                this.attachFromNode = value;
            }
        }

        public FBObject AttachToFB
        {
            get
            {
                return this.attachToFB;
            }
            set
            {
                this.attachToFB = value;
            }
        }

        public int AttachToNode
        {
            get
            {
                return this.attachToNode;
            }
            set
            {
                this.attachToNode = value;
            }
        }

        public override int HandleCount
        {
            get
            {
                return 2;
            }
        }

        public int Mid0
        {
            get
            {
                return this.mid0;
            }
            set
            {
                this.mid0 = value;
            }
        }

        public int Mid1
        {
            get
            {
                return this.mid1;
            }
            set
            {
                this.mid1 = value;
            }
        }

        public int Mid2
        {
            get
            {
                return this.mid2;
            }
            set
            {
                this.mid2 = value;
            }
        }
    }
}

